package com.hy.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.Watermark;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hy.Redis.RedisClient;
import com.hy.Redis.ValidateCodeUtils;
import com.hy.Result.ResponseResult;
import com.hy.apUser.ApPhoneuser;
import com.hy.apUser.ApUser;
import com.hy.file.service.impl.FileStorageServiceImpl;
import com.hy.mapper.ApPhoneuserMapper;
import com.hy.mapper.ApUserMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;

@Service
@Slf4j
public class ApUserServiceImpl implements APPUserService{
    @Autowired
    private ApUserMapper apUserMapper;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private ApPhoneuserMapper apPhoneuserMapper;

    @Autowired
    private FileStorageServiceImpl fileStorageService;

    //微信授权登录
    @Override
    public ResponseResult wxLogin(Map<String, Object> map) throws WxErrorException {
        Object appid = map.get("appid");
        Object secret = map.get("secret");
        Object avatarUrl = map.get("avatarUrl");
        Object nickName = map.get("nickName");
        Object code = map.get("code");
        //1获取code值，使用微信工具包对象，获取微信唯一标识
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo((String) code);
        //2 根据openid查询数据库表，判断是否第一次登录
        String openid = sessionInfo.getOpenid();
        log.info(openid+"openid");

//        //根据code值获取微信绑定手机号码
//        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(String.valueOf(code));
//
//        //获取手机号信息
//        String phoneNumber = phoneNoInfo.getPhoneNumber();
//        log.error(phoneNumber+"");
//
//        //验证数据有效性
//        Watermark watermark = phoneNoInfo.getWatermark();
//        if (!openid.equals(watermark.getAppid())) {
//            return ResponseResult.errorResult(400, "非法数据来源");
//        }

        //3 如果第一次登录，添加信息到用户表
        LambdaQueryWrapper<ApUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        ApUser apUser = apUserMapper.selectOne(lambdaQueryWrapper.eq(ApUser::getUnionId, openid));
        if(apUser == null){
            ApUser a = new ApUser();
            //* appid: 这是一个硬编码的应用 ID，'wxbe769740835caad2'，通常是微信小程序的应用标识。
            //     * secret: 这是一个硬编码的密钥，'5a72239d3fbf0d14803193abc582bf1b'，用于身份验证。
            //     * avatarUrl: 用户的头像 URL，从 uni.getUserProfile 返回的用户信息中获取。
            //     * nickName: 用户的昵称，同样是从 uni.getUserProfile 返回的用户信息中获取。
            //     * code: 从 uni.login 返回的 code，是一个临时的登录凭证，用于换取用户的授权信息。
//            a.setPhone(phoneNumber);
            a.setNickname((String) nickName);
            a.setHeadImgUrl((String) avatarUrl);
            a.setUnionId(openid);
            apUserMapper.insert(a);
            return ResponseResult.okResult(200, "登录成功！", a);
        }
        //4 记录登录日志信息
        return ResponseResult.okResult(200, "登录成功！", apUser);
    }

    //发送验证码
    @Override
    public ResponseResult sendCode(Map<String,Object> map) {
        Object phone = map.get("phone");

        // 校验手机号是否为空
        if (phone == null || StringUtils.isBlank(phone.toString())) {
            return ResponseResult.errorResult(400, "手机号不能为空!");
        }

        // 将手机号转换为字符串
        String phoneStr = phone.toString();

        // 手机号格式校验，假设是中国大陆手机号
        String phoneRegex = "^1[3-9]\\d{9}$";
        if (!Pattern.matches(phoneRegex, phoneStr)) {
            return ResponseResult.errorResult(400, "手机号格式不正确!");
        }
        //生成验证码
        Integer integer = ValidateCodeUtils.generateValidateCode(4);

        Date date = new Date();
        SimpleDateFormat s = new SimpleDateFormat();
        String format = s.format(date);

        System.err.println(format+":手机号为{"+phone+"}的用户，您的验证码为:"+integer);
        redisClient.set((String) phone, integer);
        redisClient.expire((String) phone, 60);
        return ResponseResult.okResult(200, "验证码发送成功!" );
    }

    //app用户登录
    @Override
    public ResponseResult login(Map<String, Object> map) {
        Object phone = map.get("phone");//手机号
        Object password = map.get("password");//密码
        Object code = map.get("code");//验证码
        //参数校验 校验手机号
        if (phone == null || StringUtils.isBlank(phone.toString())) {
            return ResponseResult.errorResult(400, "手机号不能为空!");
        }
        // 手机号格式校验，假设是中国大陆手机号
        String phoneRegex = "^1[3-9]\\d{9}$";
        if (!Pattern.matches(phoneRegex, phone.toString())) {
            return ResponseResult.errorResult(400, "手机号格式不正确!");
        }
        // 校验验证码
        if (code == null || StringUtils.isBlank(code.toString())) {
            return ResponseResult.errorResult(400, "验证码不能为空!");
        }

        String phonex = (String) phone;
        Object o = redisClient.get(phonex);
        if(o == null){
            return ResponseResult.errorResult(400, "验证码已失效!");
        }

        // 验证码验证
        if (!o.toString().equals(code.toString())) {
            return ResponseResult.errorResult(400, "验证码不匹配!");
        }

        //判断是否用户存在
        LambdaQueryWrapper<ApPhoneuser> lm = new LambdaQueryWrapper<>();
        lm.eq(ApPhoneuser::getPhone, phone);
        ApPhoneuser apPhoneuser = apPhoneuserMapper.selectOne(lm);
        if(apPhoneuser == null){
            return ResponseResult.errorResult(400, "您还没注册,请前往注册!");
        }
        return ResponseResult.okResult(200, "登录成功!",apPhoneuser);
    }

    //用户注册
    @Override
    public ResponseResult register(Map<String, Object> map) {
        Object o1 = map.get("code");
        Object o2 = map.get("phone");
        Object o3 = map.get("nickname");
        Object o4 = map.get("avatarUrl");
        String code = (String) o1;
        String phone = (String) o2;
        String username = (String) o3;
        String avatarUrl = (String) o4;
        //参数校验 校验手机号
        if (phone == null || StringUtils.isBlank(phone.toString())) {
            return ResponseResult.errorResult(400, "手机号不能为空!");
        }
        // 手机号格式校验，假设是中国大陆手机号
        String phoneRegex = "^1[3-9]\\d{9}$";
        if (!Pattern.matches(phoneRegex, phone.toString())) {
            return ResponseResult.errorResult(400, "手机号格式不正确!");
        }
        // 校验验证码
        if (code == null || StringUtils.isBlank(code.toString())) {
            return ResponseResult.errorResult(400, "验证码不能为空!");
        }

        String phonex = (String) phone;
        Object o = redisClient.get(phonex);
        if(o == null){
            return ResponseResult.errorResult(400, "验证码已失效!");
        }

        // 验证码验证
        if (!o.toString().equals(code.toString())) {
            return ResponseResult.errorResult(400, "验证码不匹配!");
        }

        //判断是否用户存在
        LambdaQueryWrapper<ApPhoneuser> lm = new LambdaQueryWrapper<>();
        lm.eq(ApPhoneuser::getPhone, phone);
        ApPhoneuser apPhoneuser = apPhoneuserMapper.selectOne(lm);
        if(apPhoneuser != null){
            return ResponseResult.errorResult(400, "您已经注册了,请前往注册!");
        }
        ApPhoneuser ap = new ApPhoneuser();
        ap.setUsername(username);
        ap.setAvatarUrl(avatarUrl);
        ap.setPasswordHash("");
        ap.setPhone(phone);
        ap.setGender("U");
        ap.setStatus(1);
        ap.setCreateTime(new Date());
        apPhoneuserMapper.insert(ap);
        return ResponseResult.okResult(200, "注册成功!" );
    }

    //上传头像接口
    @SneakyThrows
    @Override
    public ResponseResult<?> uploadAvatar(MultipartFile file){
        String originalFilename = file.getOriginalFilename();
        if (file.isEmpty()) {
            return ResponseResult.errorResult(400,"文件不能为空");
        }
        // 获取文件的后缀名，注意分割时需要使用 "\\." 来转义点
        String[] split = originalFilename.split("\\.");
        String fileExtension = split[split.length - 1];  // 获取文件的后缀部分
        // 生成新的文件名
        String newFileName = UUID.randomUUID().toString() + "." + fileExtension;
        System.err.println(newFileName.replace("-", ""));

        String s = fileStorageService.uploadImageFile(newFileName.replace("-", ""), file.getInputStream());
        System.err.println(s);


        return ResponseResult.okResult(200, "上传成功!",s);
    }


}
